using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Multis;
using Server.Mobiles;
using Server.Network;
using Server.ContextMenus;
using Server.Engines.Craft;
using Server.Targeting;
using Server.Gumps;
using Server.Engines.XmlSpawner2;

namespace Server.Items
{
    public enum TrapType
    {
        None,
        MagicTrap,
        ExplosionTrap,
        DartTrap,
        PoisonTrap
    }

    /// <summary>
    /// GenericContainerConfiguration
    /// </summary>

	public abstract class BaseContainer : Container, ICraftable, IEngravable
	{
		public override int DefaultMaxWeight
		{
			get
			{
				if ( IsSecure )
					return 0;

				return base.DefaultMaxWeight;
			}
		}

		private ClothingQuality m_Quality;
		private CraftResource m_Resource;
		private Mobile m_Crafter;
		private string m_EngravedText;

		[CommandProperty( AccessLevel.GameMaster )]
		public ClothingQuality Quality
		{
			get{ return m_Quality; }
			set{ m_Quality = value; InvalidateProperties(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public CraftResource Resource
		{
			get{ return m_Resource;	}
			set
			{
				if ( m_Resource != value )
				{
					m_Resource = value;
					Hue = CraftResources.GetHue( m_Resource );

					InvalidateProperties();
				}
			}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public Mobile Crafter
		{
			get{ return m_Crafter; }
			set{ m_Crafter = value; InvalidateProperties(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public string EngravedText
		{
			get{ return m_EngravedText; }
			set{ m_EngravedText = value; InvalidateProperties(); }
		}

		public BaseContainer( int itemID ) : base( itemID )
		{
		}

		public override bool IsAccessibleTo( Mobile m )
		{
			if ( !BaseHouse.CheckAccessible( m, this ) )
				return false;

			return base.IsAccessibleTo( m );
		}

		public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight )
		{
			if ( this.IsSecure && !BaseHouse.CheckHold( m, this, item, message, checkItems, plusItems, plusWeight ) )
				return false;

			return base.CheckHold( m, item, message, checkItems, plusItems, plusWeight );
		}

		public override bool CheckItemUse( Mobile from, Item item )
		{
			if ( IsDecoContainer && item is BaseBook )
				return true;

			return base.CheckItemUse( from, item );
		}

		public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
		{
			base.GetContextMenuEntries( from, list );
			SetSecureLevelEntry.AddTo( from, this, list );
		}

		public override bool TryDropItem( Mobile from, Item dropped, bool sendFullMessage )
		{
			if ( !CheckHold( from, dropped, sendFullMessage, true ) )
				return false;

			BaseHouse house = BaseHouse.FindHouseAt( this );

			if ( house != null && house.IsLockedDown( this ) )
			{
				if ( dropped is VendorRentalContract || ( dropped is Container && ((Container)dropped).FindItemByType( typeof( VendorRentalContract ) ) != null ) )
				{
					from.SendLocalizedMessage( 1062492 ); // You cannot place a rental contract in a locked down container.
					return false;
				}

				if ( !house.LockDown( from, dropped, false ) )
					return false;
			}

			List<Item> list = this.Items;

			for ( int i = 0; i < list.Count; ++i )
			{
				Item item = list[i];

				if ( !(item is Container) && item.StackWith( from, dropped, false ) )
					return true;
			}

			DropItem( dropped );

			// XmlSpawner 3.26c STEALABLE - SOF
            ItemFlags.SetTaken(dropped,true);
            // XmlSpawner 3.26c STEALABLE - EOF

			return true;
		}

		public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
		{
			if ( !CheckHold( from, item, true, true ) )
				return false;

			BaseHouse house = BaseHouse.FindHouseAt( this );

			if ( house != null && house.IsLockedDown( this ) )
			{
				if ( item is VendorRentalContract || ( item is Container && ((Container)item).FindItemByType( typeof( VendorRentalContract ) ) != null ) )
				{
					from.SendLocalizedMessage( 1062492 ); // You cannot place a rental contract in a locked down container.
					return false;
				}

				if ( !house.LockDown( from, item, false ) )
					return false;
			}

			item.Location = new Point3D( p.X, p.Y, 0 );
			AddItem( item );

			from.SendSound( GetDroppedSound( item ), GetWorldLocation() );

			// XmlSpawner 3.26c STEALABLE - SOF
            ItemFlags.SetTaken(item,true);
            // XmlSpawner 3.26c STEALABLE - EOF

			return true;
		}

		public override void UpdateTotal( Item sender, TotalType type, int delta )
		{
			base.UpdateTotal( sender, type, delta );

			if ( type == TotalType.Weight && RootParent is Mobile )
				((Mobile) RootParent).InvalidateProperties();
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( from.AccessLevel > AccessLevel.Player || from.InRange( this.GetWorldLocation(), 2 ) || this.RootParent is PlayerVendor )
				Open( from );
			else
				from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
		}

		public override void AddWeightProperty( ObjectPropertyList list )
		{
			base.AddWeightProperty( list );

			if ( m_EngravedText != null )
				list.Add( 1072305, m_EngravedText ); // Engraved: ~1_INSCRIPTION~

			if ( m_Crafter != null )
				list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~

			if ( m_Quality == ClothingQuality.Exceptional )
				list.Add( 1060636 ); // exceptional
		}

		public override void GetProperties( ObjectPropertyList list )
		{
			base.GetProperties( list );

			CraftResourceInfo info = CraftResources.IsStandard( m_Resource ) ? null : CraftResources.GetInfo( m_Resource );

			if ( info != null && info.Number > 0 )
				list.Add( info.Number );
		}

		public virtual void Open( Mobile from )
		{
			DisplayTo( from );
		}

		public BaseContainer( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( 0 ); // version

			writer.Write( (string) m_EngravedText );
			writer.Write( (int) m_Quality );
			writer.Write( (int) m_Resource );
			writer.Write( (Mobile) m_Crafter );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			m_EngravedText = reader.ReadString();
			m_Quality = (ClothingQuality) reader.ReadInt();
			m_Resource = (CraftResource) reader.ReadInt();
			m_Crafter = reader.ReadMobile();
		}

		public virtual int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
		{
			Quality = (ClothingQuality) quality;

			if ( makersMark )
				Crafter = from;

			Type resourceType = typeRes;

			if ( resourceType == null )
				resourceType = craftItem.Resources.GetAt( 0 ).ItemType;

			Resource = CraftResources.GetFromType( resourceType );

			CraftContext context = craftSystem.GetContext( from );

			if ( context != null && context.DoNotColor )
				Hue = 0;

			return quality;
		}
	}

    public abstract class TrapableContainer : BaseContainer, ITelekinesisable
    {
        private TrapType m_TrapType;
        private int m_TrapPower;
        private int m_TrapLevel;

        [CommandProperty(AccessLevel.GameMaster)]
        public TrapType TrapType
        {
            get
            {
                return m_TrapType;
            }
            set
            {
                m_TrapType = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int TrapPower
        {
            get
            {
                return m_TrapPower;
            }
            set
            {
                m_TrapPower = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int TrapLevel
        {
            get
            {
                return m_TrapLevel;
            }
            set
            {
                m_TrapLevel = value;
            }
        }

        public virtual bool TrapOnOpen { get { return true; } }

        public TrapableContainer(int itemID)
            : base(itemID)
        {
        }

        public TrapableContainer(Serial serial)
            : base(serial)
        {
        }

        private void SendMessageTo(Mobile to, int number, int hue)
        {
            if (Deleted || !to.CanSee(this))
                return;

            to.Send(new Network.MessageLocalized(Serial, ItemID, Network.MessageType.Regular, hue, 3, number, "", ""));
        }

        private void SendMessageTo(Mobile to, string text, int hue)
        {
            if (Deleted || !to.CanSee(this))
                return;

            to.Send(new Network.UnicodeMessage(Serial, ItemID, Network.MessageType.Regular, hue, 3, "ENU", "", text));
        }

        public virtual bool ExecuteTrap(Mobile from)
        {
            if (m_TrapType != TrapType.None)
            {
                Point3D loc = this.GetWorldLocation();
                Map facet = this.Map;

                if (from.AccessLevel >= AccessLevel.GameMaster)
                {
                    SendMessageTo(from, "That is trapped, but you open it with your godly powers.", 0x3B2);
                    return false;
                }

                switch (m_TrapType)
                {
                    case TrapType.ExplosionTrap:
                        {
                            SendMessageTo(from, 502999, 0x3B2); // You set off a trap!

                            if (from.InRange(loc, 3))
                            {
                                int damage;

                                if (m_TrapLevel > 0)
                                    damage = Utility.RandomMinMax(10, 30) * m_TrapLevel;
                                else
                                    damage = m_TrapPower;

                                AOS.Damage(from, damage, 0, 100, 0, 0, 0);

                                // Your skin blisters from the heat!
                                from.LocalOverheadMessage(Network.MessageType.Regular, 0x2A, 503000);
                            }

                            Effects.SendLocationEffect(loc, facet, 0x36BD, 15, 10);
                            Effects.PlaySound(loc, facet, 0x307);

                            break;
                        }
                    case TrapType.MagicTrap:
                        {
                            if (from.InRange(loc, 1))
                                from.Damage(m_TrapPower);
                            //AOS.Damage( from, m_TrapPower, 0, 100, 0, 0, 0 );

                            Effects.PlaySound(loc, Map, 0x307);

                            Effects.SendLocationEffect(new Point3D(loc.X - 1, loc.Y, loc.Z), Map, 0x36BD, 15);
                            Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y, loc.Z), Map, 0x36BD, 15);

                            Effects.SendLocationEffect(new Point3D(loc.X, loc.Y - 1, loc.Z), Map, 0x36BD, 15);
                            Effects.SendLocationEffect(new Point3D(loc.X, loc.Y + 1, loc.Z), Map, 0x36BD, 15);

                            Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y + 1, loc.Z + 11), Map, 0x36BD, 15);

                            break;
                        }
                    case TrapType.DartTrap:
                        {
                            SendMessageTo(from, 502999, 0x3B2); // You set off a trap!

                            if (from.InRange(loc, 3))
                            {
                                int damage;

                                if (m_TrapLevel > 0)
                                    damage = Utility.RandomMinMax(5, 15) * m_TrapLevel;
                                else
                                    damage = m_TrapPower;

                                AOS.Damage(from, damage, 100, 0, 0, 0, 0);

                                // A dart imbeds itself in your flesh!
                                from.LocalOverheadMessage(Network.MessageType.Regular, 0x62, 502998);
                            }

                            Effects.PlaySound(loc, facet, 0x223);

                            break;
                        }
                    case TrapType.PoisonTrap:
                        {
                            SendMessageTo(from, 502999, 0x3B2); // You set off a trap!

                            if (from.InRange(loc, 3))
                            {
                                Poison poison;

                                if (m_TrapLevel > 0)
                                {
                                    poison = Poison.GetPoison(Math.Max(0, Math.Min(4, m_TrapLevel - 1)));
                                }
                                else
                                {
                                    AOS.Damage(from, m_TrapPower, 0, 0, 0, 100, 0);
                                    poison = Poison.Greater;
                                }

                                from.ApplyPoison(from, poison);

                                // You are enveloped in a noxious green cloud!
                                from.LocalOverheadMessage(Network.MessageType.Regular, 0x44, 503004);
                            }

                            Effects.SendLocationEffect(loc, facet, 0x113A, 10, 20);
                            Effects.PlaySound(loc, facet, 0x231);

                            break;
                        }
                }

                m_TrapType = TrapType.None;
                m_TrapPower = 0;
                m_TrapLevel = 0;
                return true;
            }

            return false;
        }

        public virtual void OnTelekinesis(Mobile from)
        {
            Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022);
            Effects.PlaySound(Location, Map, 0x1F5);

            if (this.TrapOnOpen)
            {
                ExecuteTrap(from);
            }
        }

        public override void Open(Mobile from)
        {
            if (!this.TrapOnOpen || !ExecuteTrap(from))
                base.Open(from);
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)2); // version

            writer.Write((int)m_TrapLevel);

            writer.Write((int)m_TrapPower);
            writer.Write((int)m_TrapType);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 2:
                    {
                        m_TrapLevel = reader.ReadInt();
                        goto case 1;
                    }
                case 1:
                    {
                        m_TrapPower = reader.ReadInt();
                        goto case 0;
                    }
                case 0:
                    {
                        m_TrapType = (TrapType)reader.ReadInt();
                        break;
                    }
            }
        }
    }

    public abstract class LockableContainer : TrapableContainer, ILockable, ILockpickable, ICraftable, IShipwreckedItem
    {
        private bool m_Locked;
        private int m_LockLevel, m_MaxLockLevel, m_RequiredSkill;
        private uint m_KeyValue;
        private Mobile m_Picker;
        private bool m_TrapOnLockpick;

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Picker
        {
            get
            {
                return m_Picker;
            }
            set
            {
                m_Picker = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int MaxLockLevel
        {
            get
            {
                return m_MaxLockLevel;
            }
            set
            {
                m_MaxLockLevel = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int LockLevel
        {
            get
            {
                return m_LockLevel;
            }
            set
            {
                m_LockLevel = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int RequiredSkill
        {
            get
            {
                return m_RequiredSkill;
            }
            set
            {
                m_RequiredSkill = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public virtual bool Locked
        {
            get
            {
                return m_Locked;
            }
            set
            {
                m_Locked = value;

                if (m_Locked)
                    m_Picker = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public uint KeyValue
        {
            get
            {
                return m_KeyValue;
            }
            set
            {
                m_KeyValue = value;
            }
        }

        public override bool TrapOnOpen
        {
            get
            {
                return !m_TrapOnLockpick;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool TrapOnLockpick
        {
            get
            {
                return m_TrapOnLockpick;
            }
            set
            {
                m_TrapOnLockpick = value;
            }
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)6); // version

            writer.Write(m_IsShipwreckedItem);

            writer.Write((bool)m_TrapOnLockpick);
            writer.Write((int)m_RequiredSkill);
            writer.Write((int)m_MaxLockLevel);

            writer.Write(m_KeyValue);

            writer.Write((int)m_LockLevel);
            writer.Write((bool)m_Locked);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 6:
                    {
                        m_IsShipwreckedItem = reader.ReadBool();

                        goto case 5;
                    }
                case 5:
                    {
                        m_TrapOnLockpick = reader.ReadBool();

                        goto case 4;
                    }
                case 4:
                    {
                        m_RequiredSkill = reader.ReadInt();

                        goto case 3;
                    }
                case 3:
                    {
                        m_MaxLockLevel = reader.ReadInt();

                        goto case 2;
                    }
                case 2:
                    {
                        m_KeyValue = reader.ReadUInt();

                        goto case 1;
                    }
                case 1:
                    {
                        m_LockLevel = reader.ReadInt();

                        goto case 0;
                    }
                case 0:
                    {
                        if (version < 3)
                            m_MaxLockLevel = 100;

                        if (version < 4)
                        {
                            if ((m_MaxLockLevel - m_LockLevel) == 40)
                            {
                                m_RequiredSkill = m_LockLevel + 6;
                                m_LockLevel = m_RequiredSkill - 10;
                                m_MaxLockLevel = m_RequiredSkill + 39;
                            }
                            else
                            {
                                m_RequiredSkill = m_LockLevel;
                            }
                        }

                        m_Locked = reader.ReadBool();

                        break;
                    }
            }
        }

        public LockableContainer(int itemID)
            : base(itemID)
        {
            m_MaxLockLevel = 100;
        }

        public LockableContainer(Serial serial)
            : base(serial)
        {
        }

        public override bool CheckContentDisplay(Mobile from)
        {
            return !m_Locked && base.CheckContentDisplay(from);
        }

        public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage)
        {
            if (from.AccessLevel < AccessLevel.GameMaster && m_Locked)
            {
                from.SendLocalizedMessage(501747); // It appears to be locked.
                return false;
            }

            return base.TryDropItem(from, dropped, sendFullMessage);
        }

        public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
        {
            if (from.AccessLevel < AccessLevel.GameMaster && m_Locked)
            {
                from.SendLocalizedMessage(501747); // It appears to be locked.
                return false;
            }

            return base.OnDragDropInto(from, item, p);
        }

        public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
        {
            if (!base.CheckLift(from, item, ref reject))
                return false;

            if (item != this && from.AccessLevel < AccessLevel.GameMaster && m_Locked)
                return false;

            return true;
        }

        public override bool CheckItemUse(Mobile from, Item item)
        {
            if (!base.CheckItemUse(from, item))
                return false;

            if (item != this && from.AccessLevel < AccessLevel.GameMaster && m_Locked)
            {
                from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
                return false;
            }

            return true;
        }

        public override bool DisplaysContent { get { return !m_Locked; } }

        public virtual bool CheckLocked(Mobile from)
        {
            bool inaccessible = false;

            if (m_Locked)
            {
                int number;

                if (from.AccessLevel >= AccessLevel.GameMaster)
                {
                    number = 502502; // That is locked, but you open it with your godly powers.
                }
                else
                {
                    number = 501747; // It appears to be locked.
                    inaccessible = true;
                }

                from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", ""));
            }

            return inaccessible;
        }

        public override void OnTelekinesis(Mobile from)
        {
            if (CheckLocked(from))
            {
                Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022);
                Effects.PlaySound(Location, Map, 0x1F5);
                return;
            }

            base.OnTelekinesis(from);
        }

        public override void OnDoubleClickSecureTrade(Mobile from)
        {
            if (CheckLocked(from))
                return;

            base.OnDoubleClickSecureTrade(from);
        }

        public override void Open(Mobile from)
        {
            if (CheckLocked(from))
                return;

            base.Open(from);
        }

        public override void OnSnoop(Mobile from)
        {
            if (CheckLocked(from))
                return;

            base.OnSnoop(from);
        }

        public virtual void LockPick(Mobile from)
        {
            Locked = false;
            Picker = from;

            if (this.TrapOnLockpick && ExecuteTrap(from))
            {
                this.TrapOnLockpick = false;
            }
        }

        public override void AddNameProperties(ObjectPropertyList list)
        {
            base.AddNameProperties(list);

            if (m_IsShipwreckedItem)
                list.Add(1041645); // recovered from a shipwreck
        }

        public override void OnSingleClick(Mobile from)
        {
            base.OnSingleClick(from);

            if (m_IsShipwreckedItem)
                LabelTo(from, 1041645);	//recovered from a shipwreck
        }

        public override int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue)
        {
            if (from.CheckSkill(SkillName.Tinkering, -5.0, 15.0))
            {
                from.SendLocalizedMessage(500636); // Your tinker skill was sufficient to make the item lockable.

                Key key = new Key(KeyType.Copper, Key.RandomValue());

                KeyValue = key.KeyValue;
                DropItem(key);

                double tinkering = from.Skills[SkillName.Tinkering].Value;
                int level = (int)(tinkering * 0.8);

                RequiredSkill = level - 4;
                LockLevel = level - 14;
                MaxLockLevel = level + 35;

                if (LockLevel == 0)
                    LockLevel = -1;
                else if (LockLevel > 95)
                    LockLevel = 95;

                if (RequiredSkill > 95)
                    RequiredSkill = 95;

                if (MaxLockLevel > 95)
                    MaxLockLevel = 95;
            }
            else
            {
                from.SendLocalizedMessage(500637); // Your tinker skill was insufficient to make the item lockable.
            }

            return base.OnCraft(quality, makersMark, from, craftSystem, typeRes, tool, craftItem, resHue);
        }

        private bool m_IsShipwreckedItem;

        [CommandProperty(AccessLevel.GameMaster)]
        public bool IsShipwreckedItem
        {
            get { return m_IsShipwreckedItem; }
            set { m_IsShipwreckedItem = value; }
        }
    }
 
    #region Generic Container Type List

    #region CreatureBackpack

    public class CreatureBackpack : Backpack	//Used on BaseCreature
    {
        [Constructable]
        public CreatureBackpack(string name)
        {
            Name = name;
            Layer = Layer.Backpack;
            Hue = 5;
            Weight = 3.0;
        }

        public override void AddNameProperty(ObjectPropertyList list)
        {
            if (Name != null)
                list.Add(1075257, Name); // Contents of ~1_PETNAME~'s pack.
            else
                base.AddNameProperty(list);
        }

        public override void OnItemRemoved(Item item)
        {
            if (Items.Count == 0)
                this.Delete();

            base.OnItemRemoved(item);
        }

        public override bool OnDragLift(Mobile from)
        {
            if (from.AccessLevel > AccessLevel.Player)
                return true;

            from.SendLocalizedMessage(500169); // You cannot pick that up.
            return false;
        }

        public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
        {
            return false;
        }

        public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage)
        {
            return false;
        }

        public CreatureBackpack(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0)
                Weight = 13.0;
        }
    }

    #endregion Edited By: A.A.R

    #region StrongBackpack

    public class StrongBackpack : Backpack	//Used on Pack animals
    {
        [Constructable]
        public StrongBackpack()
        {
            Layer = Layer.Backpack;
            Weight = 13.0;
        }

        public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
        {
            return base.CheckHold(m, item, false, checkItems, plusItems, plusWeight);
        }

        public override int DefaultMaxWeight { get { return 1600; } }

        public override bool CheckContentDisplay(Mobile from)
        {
            object root = this.RootParent;

            if (root is BaseCreature && ((BaseCreature)root).Controlled && ((BaseCreature)root).ControlMaster == from)
                return true;

            return base.CheckContentDisplay(from);
        }

        public override void UpdateTotal(Item sender, TotalType type, int delta)
        {
            base.UpdateTotal(sender, type, delta);

            if (type == TotalType.Weight && RootParent is Mobile)
                ((Mobile)RootParent).InvalidateProperties();
        }

        public StrongBackpack(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0)
                Weight = 13.0;
        }
    }

    #endregion Edited By: A.A.R

    #region Backpack

    public class Backpack : BaseContainer, IDyable
    {
        [Constructable]
        public Backpack()
            : base(0xE75)
        {
            Layer = Layer.Backpack;
            Weight = 3.0;
        }

        public override int DefaultMaxWeight
        {
            get
            {
                if (Core.ML)
                {
                    Mobile m = ParentEntity as Mobile;
                    if (m != null && m.Player && m.Backpack == this)
                    {
                        return 550;
                    }
                    else
                    {
                        return base.DefaultMaxWeight;
                    }
                }
                else
                {
                    return base.DefaultMaxWeight;
                }
            }
        }

        public Backpack(Serial serial)
            : base(serial)
        {
        }

        public bool Dye(Mobile from, DyeTub sender)
        {
            if (Deleted) return false;

            Hue = sender.DyedHue;

            return true;
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && ItemID == 0x9B2)
                ItemID = 0xE75;
        }
    }

    #endregion Edited By: A.A.R

    #region TrapableContainer

    public class Pouch : TrapableContainer
    {
        [Constructable]
        public Pouch()
            : base(0xE79)
        {
            Weight = 1.0;
        }

        public Pouch(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    class TrappedClosedbarrel : TrapableContainer
    {
        public override int DefaultGumpID { get { return 0x3e; } }

        [Constructable]
        public TrappedClosedbarrel()
            : base(0x0FAE)
        {
        }

        public TrappedClosedbarrel(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region BagBall

    public abstract class BaseBagBall : BaseContainer, IDyable
    {
        public BaseBagBall(int itemID)
            : base(itemID)
        {
            Weight = 1.0;
        }

        public BaseBagBall(Serial serial)
            : base(serial)
        {
        }

        public bool Dye(Mobile from, DyeTub sender)
        {
            if (Deleted)
                return false;

            Hue = sender.DyedHue;

            return true;
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    public class SmallBagBall : BaseBagBall
    {
        [Constructable]
        public SmallBagBall()
            : base(0x2256)
        {
        }

        public SmallBagBall(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    public class LargeBagBall : BaseBagBall
    {
        [Constructable]
        public LargeBagBall()
            : base(0x2257)
        {
        }

        public LargeBagBall(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region Bag

    public class Bag : BaseContainer, IDyable
    {
        [Constructable]
        public Bag()
            : base(0xE76)
        {
            Weight = 2.0;
        }

        public Bag(Serial serial)
            : base(serial)
        {
        }

        public bool Dye(Mobile from, DyeTub sender)
        {
            if (Deleted) return false;

            Hue = sender.DyedHue;

            return true;
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region Barrel

    public class Barrel : BaseContainer
    {
        [Constructable]
        public Barrel(): base(0xE77)
        {
            Weight = 25.0;
        }

        public Barrel(Serial serial): base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 0.0)
                Weight = 25.0;
        }
    }

    public class ClosedBarrel : BaseContainer
    {
        public override int DefaultDropSound { get { return 0x42; } }

        public override int DefaultGumpID { get { return 0x3E; } }

        [Constructable]
        public ClosedBarrel(): base(0x0FAE)
        {
            Weight = 25.0;

        }

        public ClosedBarrel(Serial serial): base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 0.0)
                Weight = 25.0;
        }
    }

    #endregion Edited By: A.A.R

    #region Keg

    public class Keg : BaseContainer
    {
        [Constructable]
        public Keg()
            : base(0xE7F)
        {
            Weight = 15.0;
        }

        public Keg(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region PicnicBasket

    public class PicnicBasket : BaseContainer
    {
        [Constructable]
        public PicnicBasket()
            : base(0xE7A)
        {
            Weight = 2.0; // Stratics doesn't know weight
        }

        public PicnicBasket(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region Basket

    public class Basket : BaseContainer
    {
        [Constructable]
        public Basket()
            : base(0x990)
        {
            Weight = 1.0; // Stratics doesn't know weight
        }

        public Basket(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region WoodenBox

    [Furniture]
    [Flipable(0x9AA, 0xE7D)]
    public class WoodenBox : LockableContainer
    {
        [Constructable]
        public WoodenBox()
            : base(0x9AA)
        {
            Weight = 4.0;
        }

        public WoodenBox(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region SmallCrate

    [Furniture]
    [Flipable(0x9A9, 0xE7E)]
    public class SmallCrate : LockableContainer
    {
        [Constructable]
        public SmallCrate()
            : base(0x9A9)
        {
            Weight = 2.0;
        }

        public SmallCrate(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 4.0)
                Weight = 2.0;
        }
    }

    #endregion Edited By: A.A.R

    #region MediumCrate

    [Furniture]
    [Flipable(0xE3F, 0xE3E)]
    public class MediumCrate : LockableContainer
    {
        [Constructable]
        public MediumCrate()
            : base(0xE3F)
        {
            Weight = 2.0;
        }

        public MediumCrate(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 6.0)
                Weight = 2.0;
        }
    }

    #endregion Edited By: A.A.R

    #region LargeCrate

    [Furniture]
    [Flipable(0xE3D, 0xE3C)]
    public class LargeCrate : LockableContainer
    {
        [Constructable]
        public LargeCrate()
            : base(0xE3D)
        {
            Weight = 1.0;
        }

        public LargeCrate(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 8.0)
                Weight = 1.0;
        }
    }

    #endregion Edited By: A.A.R

    #region MetalBox

    [DynamicFliping]
    [Flipable(0x9A8, 0xE80)]
    public class MetalBox : LockableContainer
    {
        [Constructable]
        public MetalBox()
            : base(0x9A8)
        {
        }

        public MetalBox(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 3)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region MetalChest

    [DynamicFliping]
    [Flipable(0x9AB, 0xE7C)]
    public class MetalChest : LockableContainer
    {
        [Constructable]
        public MetalChest()
            : base(0x9AB)
        {
        }

        public MetalChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 25)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region MetalGoldenChest

    [DynamicFliping]
    [Flipable(0xE41, 0xE40)]
    public class MetalGoldenChest : LockableContainer
    {
        [Constructable]
        public MetalGoldenChest()
            : base(0xE41)
        {
        }

        public MetalGoldenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 25)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region WoodenChest

    [Furniture]
    [Flipable(0xe43, 0xe42)]
    public class WoodenChest : LockableContainer
    {
        [Constructable]
        public WoodenChest()
            : base(0xe43)
        {
            Weight = 2.0;
        }

        public WoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (Weight == 15.0)
                Weight = 2.0;
        }
    }

    #endregion Edited By: A.A.R

    #region PlainWoodenChest

    [Furniture]
    [Flipable(0x280B, 0x280C)]
    public class PlainWoodenChest : LockableContainer
    {
        [Constructable]
        public PlainWoodenChest()
            : base(0x280B)
        {
        }

        public PlainWoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 15)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region OrnateWoodenChest

    [Furniture]
    [Flipable(0x280D, 0x280E)]
    public class OrnateWoodenChest : LockableContainer
    {
        [Constructable]
        public OrnateWoodenChest()
            : base(0x280D)
        {
        }

        public OrnateWoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 15)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region GildedWoodenChest

    [Furniture]
    [Flipable(0x280F, 0x2810)]
    public class GildedWoodenChest : LockableContainer
    {
        [Constructable]
        public GildedWoodenChest()
            : base(0x280F)
        {
        }

        public GildedWoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 15)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region WoodenFootLocker

    [Furniture]
    [Flipable(0x2811, 0x2812)]
    public class WoodenFootLocker : LockableContainer
    {
        [Constructable]
        public WoodenFootLocker()
            : base(0x2811)
        {
            GumpID = 0x10B;
        }

        public WoodenFootLocker(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)2); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 15)
                Weight = -1;

            if (version < 2)
                GumpID = 0x10B;
        }
    }

    #endregion Edited By: A.A.R

    #region FinishedWoodenChest

    [Furniture]
    [Flipable(0x2813, 0x2814)]
    public class FinishedWoodenChest : LockableContainer
    {
        [Constructable]
        public FinishedWoodenChest()
            : base(0x2813)
        {
        }

        public FinishedWoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 15)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region StrongBox

    [FlipableAttribute(0xE80, 0x9A8)]
    public class StrongBox : BaseContainer, IChopable
    {
        private Mobile m_Owner;
        private BaseHouse m_House;

        public override double DefaultWeight { get { return 100; } }
        public override int LabelNumber { get { return 1023712; } }

        public StrongBox(Mobile owner, BaseHouse house)
            : base(0xE80)
        {
            m_Owner = owner;
            m_House = house;

            MaxItems = 25;
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Owner
        {
            get
            {
                return m_Owner;
            }
            set
            {
                m_Owner = value;
                InvalidateProperties();
            }
        }

        public override int DefaultMaxWeight { get { return 0; } }

        public StrongBox(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version

            writer.Write(m_Owner);
            writer.Write(m_House);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 0:
                    {
                        m_Owner = reader.ReadMobile();
                        m_House = reader.ReadItem() as BaseHouse;

                        break;
                    }
            }

            Timer.DelayCall(TimeSpan.FromSeconds(1.0), new TimerCallback(Validate));
        }

        private void Validate()
        {
            if (m_Owner != null && m_House != null && !m_House.IsCoOwner(m_Owner))
            {
                Console.WriteLine("Warning: Destroying strongbox of {0}", m_Owner.Name);
                Destroy();
            }
        }

        public override bool Decays
        {
            get
            {
                if (m_House != null && m_Owner != null && !m_Owner.Deleted)
                    return !m_House.IsCoOwner(m_Owner);
                else
                    return true;
            }
        }

        public override TimeSpan DecayTime
        {
            get
            {
                return TimeSpan.FromMinutes(30.0);
            }
        }

        public override void AddNameProperty(ObjectPropertyList list)
        {
            if (m_Owner != null)
                list.Add(1042887, m_Owner.Name); // a strong box owned by ~1_OWNER_NAME~
            else
                base.AddNameProperty(list);
        }

        public override void OnSingleClick(Mobile from)
        {
            if (m_Owner != null)
            {
                LabelTo(from, 1042887, m_Owner.Name); // a strong box owned by ~1_OWNER_NAME~

                if (CheckContentDisplay(from))
                    LabelTo(from, "({0} items, {1} stones)", TotalItems, TotalWeight);
            }
            else
            {
                base.OnSingleClick(from);
            }
        }

        public override bool IsAccessibleTo(Mobile m)
        {
            if (m_Owner == null || m_Owner.Deleted || m_House == null || m_House.Deleted || m.AccessLevel >= AccessLevel.GameMaster)
                return true;

            return m == m_Owner && m_House.IsCoOwner(m) && base.IsAccessibleTo(m);
        }

        private void Chop(Mobile from)
        {
            Effects.PlaySound(Location, Map, 0x3B3);
            from.SendLocalizedMessage(500461); // You destroy the item.
            Destroy();
        }

        public void OnChop(Mobile from)
        {
            if (m_House != null && !m_House.Deleted && m_Owner != null && !m_Owner.Deleted)
            {
                if (from == m_Owner || m_House.IsOwner(from))
                    Chop(from);
            }
            else
            {
                Chop(from);
            }
        }

        public Container ConvertToStandardContainer()
        {
            Container metalBox = new MetalBox();
            List<Item> subItems = new List<Item>(Items);

            foreach (Item subItem in subItems)
            {
                metalBox.AddItem(subItem);
            }

            this.Delete();

            return metalBox;
        }
    }

    #endregion Edited By: A.A.R

    #endregion Edited By: A.A.R

    
    //------------------------------------------------------------------------------------//


    /// <summary>
    /// FillableContainerConfiguration
    /// </summary>

    public abstract class FillableContainer : LockableContainer
    {
        public virtual int MinRespawnMinutes { get { return 60; } }
        public virtual int MaxRespawnMinutes { get { return 90; } }

        public virtual bool IsLockable { get { return true; } }
        public virtual bool IsTrapable { get { return IsLockable; } }

        public virtual int SpawnThreshold { get { return 2; } }

        protected FillableContent m_Content;

        protected DateTime m_NextRespawnTime;
        protected Timer m_RespawnTimer;

        [CommandProperty(AccessLevel.GameMaster)]
        public DateTime NextRespawnTime { get { return m_NextRespawnTime; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public FillableContentType ContentType
        {
            get { return FillableContent.Lookup(m_Content); }
            set { Content = FillableContent.Lookup(value); }
        }

        public FillableContent Content
        {
            get { return m_Content; }
            set
            {
                if (m_Content == value)
                    return;

                m_Content = value;

                for (int i = Items.Count - 1; i >= 0; --i)
                {
                    if (i < Items.Count)
                        Items[i].Delete();
                }

                Respawn();
            }
        }

        public FillableContainer(int itemID): base(itemID)
        {
            Movable = false;
        }

        public override void OnMapChange()
        {
            base.OnMapChange();
            AcquireContent();
        }

        public override void OnLocationChange(Point3D oldLocation)
        {
            base.OnLocationChange(oldLocation);
            AcquireContent();
        }

        public virtual void AcquireContent()
        {
            if (m_Content != null)
                return;

            m_Content = FillableContent.Acquire(this.GetWorldLocation(), this.Map);

            if (m_Content != null)
                Respawn();
        }

        public override void OnItemRemoved(Item item)
        {
            CheckRespawn();
        }

        public override void OnAfterDelete()
        {
            base.OnAfterDelete();

            if (m_RespawnTimer != null)
            {
                m_RespawnTimer.Stop();
                m_RespawnTimer = null;
            }
        }

        public int GetItemsCount()
        {
            int count = 0;

            foreach (Item item in this.Items)
            {
                count += item.Amount;
            }

            return count;
        }

        public void CheckRespawn()
        {
            bool canSpawn = (m_Content != null && !Deleted && GetItemsCount() <= SpawnThreshold && !Movable && Parent == null && !IsLockedDown && !IsSecure);

            if (canSpawn)
            {
                if (m_RespawnTimer == null)
                {
                    int mins = Utility.RandomMinMax(this.MinRespawnMinutes, this.MaxRespawnMinutes);
                    TimeSpan delay = TimeSpan.FromMinutes(mins);

                    m_NextRespawnTime = DateTime.Now + delay;
                    m_RespawnTimer = Timer.DelayCall(delay, new TimerCallback(Respawn));
                }
            }
            else if (m_RespawnTimer != null)
            {
                m_RespawnTimer.Stop();
                m_RespawnTimer = null;
            }
        }

        public void Respawn()
        {
            if (m_RespawnTimer != null)
            {
                m_RespawnTimer.Stop();
                m_RespawnTimer = null;
            }

            if (m_Content == null || Deleted)
                return;

            GenerateContent();

            if (IsLockable)
            {
                Locked = true;

                int difficulty = (m_Content.Level - 1) * 30;

                LockLevel = difficulty - 10;
                MaxLockLevel = difficulty + 30;
                RequiredSkill = difficulty;
            }

            if (IsTrapable && (m_Content.Level > 1 || 4 > Utility.Random(5)))
            {
                if (m_Content.Level > Utility.Random(5))
                    TrapType = TrapType.PoisonTrap;
                else
                    TrapType = TrapType.ExplosionTrap;

                TrapPower = m_Content.Level * Utility.RandomMinMax(10, 30);
                TrapLevel = m_Content.Level;
            }
            else
            {
                TrapType = TrapType.None;
                TrapPower = 0;
                TrapLevel = 0;
            }

            CheckRespawn();
        }

        protected virtual int GetSpawnCount()
        {
            int itemsCount = GetItemsCount();

            if (itemsCount > SpawnThreshold)
                return 0;

            int maxSpawnCount = (1 + SpawnThreshold - itemsCount) * 2;

            return Utility.RandomMinMax(0, maxSpawnCount);
        }

        public virtual void GenerateContent()
        {
            if (m_Content == null || Deleted)
                return;

            int toSpawn = GetSpawnCount();

            for (int i = 0; i < toSpawn; ++i)
            {
                Item item = m_Content.Construct();

                if (item != null)
                {
                    List<Item> list = this.Items;

                    for (int j = 0; j < list.Count; ++j)
                    {
                        Item subItem = list[j];

                        if (!(subItem is Container) && subItem.StackWith(null, item, false))
                            break;
                    }

                    if (item != null && !item.Deleted)
                        DropItem(item);
                }
            }
        }

        public FillableContainer(Serial serial): base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt(1); // version

            writer.Write((int)ContentType);

            if (m_RespawnTimer != null)
            {
                writer.Write(true);
                writer.WriteDeltaTime((DateTime)m_NextRespawnTime);
            }
            else
            {
                writer.Write(false);
            }
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();

            switch (version)
            {
                case 1:
                    {
                        m_Content = FillableContent.Lookup((FillableContentType)reader.ReadInt());
                        goto case 0;
                    }
                case 0:
                    {
                        if (reader.ReadBool())
                        {
                            m_NextRespawnTime = reader.ReadDeltaTime();

                            TimeSpan delay = m_NextRespawnTime - DateTime.Now;
                            m_RespawnTimer = Timer.DelayCall(delay > TimeSpan.Zero ? delay : TimeSpan.Zero, new TimerCallback(Respawn));
                        }
                        else
                        {
                            CheckRespawn();
                        }

                        break;
                    }
            }
        }
    }

    public class FillableEntry
    {
        protected Type[] m_Types;
        protected int m_Weight;

        public Type[] Types { get { return m_Types; } }
        public int Weight { get { return m_Weight; } }

        public FillableEntry(Type type)
            : this(1, new Type[] { type })
        {
        }

        public FillableEntry(int weight, Type type)
            : this(weight, new Type[] { type })
        {
        }

        public FillableEntry(Type[] types)
            : this(1, types)
        {
        }

        public FillableEntry(int weight, Type[] types)
        {
            m_Weight = weight;
            m_Types = types;
        }

        public FillableEntry(int weight, Type[] types, int offset, int count)
        {
            m_Weight = weight;
            m_Types = new Type[count];

            for (int i = 0; i < m_Types.Length; ++i)
                m_Types[i] = types[offset + i];
        }

        public virtual Item Construct()
        {
            Item item = Loot.Construct(m_Types);

            if (item is Key)
                ((Key)item).ItemID = Utility.RandomList((int)KeyType.Copper, (int)KeyType.Gold, (int)KeyType.Iron, (int)KeyType.Rusty);
            else if (item is Arrow || item is Bolt)
                item.Amount = Utility.RandomMinMax(2, 6);
            else if (item is Bandage || item is Lockpick)
                item.Amount = Utility.RandomMinMax(1, 3);

            return item;
        }
    }

    public class FillableBvrge : FillableEntry
    {
        private BeverageType m_Content;

        public BeverageType Content { get { return m_Content; } }

        public FillableBvrge(Type type, BeverageType content)
            : this(1, type, content)
        {
        }

        public FillableBvrge(int weight, Type type, BeverageType content)
            : base(weight, type)
        {
            m_Content = content;
        }

        public override Item Construct()
        {
            Item item;

            int index = Utility.Random(m_Types.Length);

            if (m_Types[index] == typeof(BeverageBottle))
            {
                item = new BeverageBottle(m_Content);
            }
            else if (m_Types[index] == typeof(Jug))
            {
                item = new Jug(m_Content);
            }
            else
            {
                item = base.Construct();

                if (item is BaseBeverage)
                {
                    BaseBeverage bev = (BaseBeverage)item;

                    bev.Content = m_Content;
                    bev.Quantity = bev.MaxQuantity;
                }
            }

            return item;
        }
    }

    public enum FillableContentType
    {
        None = -1,
        Weaponsmith, Provisioner, Mage,
        Alchemist, Armorer, ArtisanGuild,
        Baker, Bard, Blacksmith,
        Bowyer, Butcher, Carpenter,
        Clothier, Cobbler, Docks,
        Farm, FighterGuild, Guard,
        Healer, Herbalist, Inn,
        Jeweler, Library, Merchant,
        Mill, Mine, Observatory,
        Painter, Ranger, Stables,
        Tanner, Tavern, ThiefGuild,
        Tinker, Veterinarian
    }

    public class FillableContent
    {
        private int m_Level;
        private Type[] m_Vendors;

        private FillableEntry[] m_Entries;
        private int m_Weight;

        public int Level { get { return m_Level; } }
        public Type[] Vendors { get { return m_Vendors; } }

        public FillableContentType TypeID { get { return Lookup(this); } }

        public FillableContent(int level, Type[] vendors, FillableEntry[] entries)
        {
            m_Level = level;
            m_Vendors = vendors;
            m_Entries = entries;

            for (int i = 0; i < entries.Length; ++i)
                m_Weight += entries[i].Weight;
        }

        public virtual Item Construct()
        {
            int index = Utility.Random(m_Weight);

            for (int i = 0; i < m_Entries.Length; ++i)
            {
                FillableEntry entry = m_Entries[i];

                if (index < entry.Weight)
                    return entry.Construct();

                index -= entry.Weight;
            }

            return null;
        }

        public static FillableContent Alchemist = new FillableContent(
            1,
            new Type[]
			{
				typeof( Mobiles.Alchemist )
			},
            new FillableEntry[]
			{
				new FillableEntry( typeof( NightSightPotion ) ),
				new FillableEntry( typeof( LesserCurePotion ) ),
				new FillableEntry( typeof( AgilityPotion ) ),
				new FillableEntry( typeof( StrengthPotion ) ),
				new FillableEntry( typeof( LesserPoisonPotion ) ),
				new FillableEntry( typeof( RefreshPotion ) ),
				new FillableEntry( typeof( LesserHealPotion ) ),
				new FillableEntry( typeof( LesserExplosionPotion ) ),
				new FillableEntry( typeof( MortarPestle ) )
			});

        public static FillableContent Armorer = new FillableContent(
            2,
            new Type[]
			{
				typeof( Armorer )
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( ChainCoif ) ),
				new FillableEntry( 1, typeof( PlateGorget ) ),
				new FillableEntry( 1, typeof( BronzeShield ) ),
				new FillableEntry( 1, typeof( Buckler ) ),
				new FillableEntry( 2, typeof( MetalKiteShield ) ),
				new FillableEntry( 2, typeof( HeaterShield ) ),
				new FillableEntry( 1, typeof( WoodenShield ) ),
				new FillableEntry( 1, typeof( MetalShield ) )
			});

        public static FillableContent ArtisanGuild = new FillableContent(
            1,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( PaintsAndBrush ) ),
				new FillableEntry( 1, typeof( SledgeHammer ) ),
				new FillableEntry( 2, typeof( SmithHammer ) ),
				new FillableEntry( 2, typeof( Tongs ) ),
				new FillableEntry( 4, typeof( Lockpick ) ),
				new FillableEntry( 4, typeof( TinkerTools ) ),
				new FillableEntry( 1, typeof( MalletAndChisel ) ),
				new FillableEntry( 1, typeof( StatueEast2 ) ),
				new FillableEntry( 1, typeof( StatueSouth ) ),
				new FillableEntry( 1, typeof( StatueSouthEast ) ),
				new FillableEntry( 1, typeof( StatueWest ) ),
				new FillableEntry( 1, typeof( StatueNorth ) ),
				new FillableEntry( 1, typeof( StatueEast ) ),
				new FillableEntry( 1, typeof( BustEast ) ),
				new FillableEntry( 1, typeof( BustSouth ) ),
				new FillableEntry( 1, typeof( BearMask ) ),
				new FillableEntry( 1, typeof( DeerMask ) ),
				new FillableEntry( 4, typeof( OrcHelm ) ),
				new FillableEntry( 1, typeof( TribalMask ) ),
				new FillableEntry( 1, typeof( HornedTribalMask ) )
			});

        public static FillableContent Baker = new FillableContent(
            1,
            new Type[]
			{
				typeof( Baker ),
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( RollingPin ) ),
				new FillableEntry( 2, typeof( SackFlour ) ),
				new FillableEntry( 2, typeof( BreadLoaf ) ),
				new FillableEntry( 1, typeof( FrenchBread ) )
			});

        public static FillableContent Bard = new FillableContent(
            1,
            new Type[]
			{
				typeof( Bard ),
				typeof( BardGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( LapHarp ) ),
				new FillableEntry( 2, typeof( Lute ) ),
				new FillableEntry( 1, typeof( Drums ) ),
				new FillableEntry( 1, typeof( Tambourine ) ),
				new FillableEntry( 1, typeof( TambourineTassel ) )
			});

        public static FillableContent Blacksmith = new FillableContent(
            2,
            new Type[]
			{
				typeof( Blacksmith ),
				typeof( BlacksmithGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 8, typeof( SmithHammer ) ),
				new FillableEntry( 8, typeof( Tongs ) ),
				new FillableEntry( 8, typeof( SledgeHammer ) ),
				new FillableEntry( 8, typeof( IronIngot ) ),
				new FillableEntry( 1, typeof( IronWire ) ),
				new FillableEntry( 1, typeof( SilverWire ) ),
				new FillableEntry( 1, typeof( GoldWire ) ),
				new FillableEntry( 1, typeof( CopperWire ) ),
				new FillableEntry( 1, typeof( HorseShoes ) ),
				new FillableEntry( 1, typeof( ForgedMetal ) )
			});

        public static FillableContent Bowyer = new FillableContent(
            2,
            new Type[]
			{
				typeof( Bowyer )
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( Bow ) ),
				new FillableEntry( 2, typeof( Crossbow ) ),
				new FillableEntry( 1, typeof( Arrow ) )
			});

        public static FillableContent Butcher = new FillableContent(
            1,
            new Type[]
			{
				typeof( Butcher ),
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( Cleaver ) ),
				new FillableEntry( 2, typeof( SlabOfBacon ) ),
				new FillableEntry( 2, typeof( Bacon ) ),
				new FillableEntry( 1, typeof( RawFishSteak ) ),
				new FillableEntry( 1, typeof( FishSteak ) ),
				new FillableEntry( 2, typeof( CookedBird ) ),
				new FillableEntry( 2, typeof( RawBird ) ),
				new FillableEntry( 2, typeof( Ham ) ),
				new FillableEntry( 1, typeof( RawLambLeg ) ),
				new FillableEntry( 1, typeof( LambLeg ) ),
				new FillableEntry( 1, typeof( Ribs ) ),
				new FillableEntry( 1, typeof( RawRibs ) ),
				new FillableEntry( 2, typeof( Sausage ) ),
				new FillableEntry( 1, typeof( RawChickenLeg ) ),
				new FillableEntry( 1, typeof( ChickenLeg ) )
			});

        public static FillableContent Carpenter = new FillableContent(
            1,
            new Type[]
			{
				typeof( Carpenter ),
				typeof( Architect ),
				typeof( RealEstateBroker )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( ChiselsNorth ) ),
				new FillableEntry( 1, typeof( ChiselsWest ) ),
				new FillableEntry( 2, typeof( DovetailSaw ) ),
				new FillableEntry( 2, typeof( Hammer ) ),
				new FillableEntry( 2, typeof( MouldingPlane ) ),
				new FillableEntry( 2, typeof( Nails ) ),
				new FillableEntry( 2, typeof( JointingPlane ) ),
				new FillableEntry( 2, typeof( SmoothingPlane ) ),
				new FillableEntry( 2, typeof( Saw ) ),
				new FillableEntry( 2, typeof( DrawKnife ) ),
				new FillableEntry( 1, typeof( Log ) ),
				new FillableEntry( 1, typeof( Froe ) ),
				new FillableEntry( 1, typeof( Inshave ) ),
				new FillableEntry( 1, typeof( Scorp ) )
			});

        public static FillableContent Clothier = new FillableContent(
            1,
            new Type[]
			{
				typeof( Tailor ),
				typeof( Weaver ),
				typeof( TailorGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Cotton ) ),
				new FillableEntry( 1, typeof( Wool ) ),
				new FillableEntry( 1, typeof( DarkYarn ) ),
				new FillableEntry( 1, typeof( LightYarn ) ),
				new FillableEntry( 1, typeof( LightYarnUnraveled ) ),
				new FillableEntry( 1, typeof( SpoolOfThread ) ),
				new FillableEntry( 1, typeof( Dyes ) ),
				new FillableEntry( 2, typeof( Leather ) )
			});

        public static FillableContent Cobbler = new FillableContent(
            1,
            new Type[]
			{
				typeof( Cobbler )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Boots ) ),
				new FillableEntry( 2, typeof( Shoes ) ),
				new FillableEntry( 2, typeof( Sandals ) ),
				new FillableEntry( 1, typeof( ThighBoots ) )
			});

        public static FillableContent Docks = new FillableContent(
            1,
            new Type[]
			{
				typeof( Fisherman ),
				typeof( FisherGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( FishingPole ) ),
				new FillableEntry( 4, typeof( Fish ) )
			});

        public static FillableContent Farm = new FillableContent(
            1,
            new Type[]
			{
				typeof( Farmer ),
				typeof( Rancher )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Shirt ) ),
				new FillableEntry( 1, typeof( ShortPants ) ),
				new FillableEntry( 1, typeof( Skirt ) ),
				new FillableEntry( 1, typeof( PlainDress ) ),
				new FillableEntry( 1, typeof( Cap ) ),
				new FillableEntry( 2, typeof( Sandals ) ),
				new FillableEntry( 2, typeof( GnarledStaff ) ),
				new FillableEntry( 2, typeof( Pitchfork ) ),
				new FillableEntry( 1, typeof( Bag ) ),
				new FillableEntry( 1, typeof( Kindling ) ),
				new FillableEntry( 1, typeof( Lettuce ) ),
				new FillableEntry( 1, typeof( Onion ) ),
				new FillableEntry( 1, typeof( Turnip ) ),
				new FillableEntry( 1, typeof( Ham ) ),
				new FillableEntry( 1, typeof( Bacon ) ),
				new FillableEntry( 1, typeof( RawLambLeg ) ),
				new FillableEntry( 1, typeof( SheafOfHay ) ),
				new FillableBvrge( 1, typeof( Pitcher ), BeverageType.Milk )
			});

        public static FillableContent FighterGuild = new FillableContent(
            3,
            new Type[]
			{
				typeof( WarriorGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 12, Loot.ArmorTypes ),
				new FillableEntry(  8, Loot.WeaponTypes ),
				new FillableEntry(  3, Loot.ShieldTypes ),
				new FillableEntry(  1, typeof( Arrow ) )
			});

        public static FillableContent Guard = new FillableContent(
            3,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 12, Loot.ArmorTypes ),
				new FillableEntry(  8, Loot.WeaponTypes ),
				new FillableEntry(  3, Loot.ShieldTypes ),
				new FillableEntry(  1, typeof( Arrow ) )
			});

        public static FillableContent Healer = new FillableContent(
            1,
            new Type[]
			{
				typeof( Healer ),
				typeof( HealerGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Bandage ) ),
				new FillableEntry( 1, typeof( MortarPestle ) ),
				new FillableEntry( 1, typeof( LesserHealPotion ) )
			});

        public static FillableContent Herbalist = new FillableContent(
            1,
            new Type[]
			{
				typeof( Herbalist )
			},
            new FillableEntry[]
			{
				new FillableEntry( 10, typeof( Garlic ) ),
				new FillableEntry( 10, typeof( Ginseng ) ),
				new FillableEntry( 10, typeof( MandrakeRoot ) ),
				new FillableEntry(  1, typeof( DeadWood ) ),
				new FillableEntry(  1, typeof( WhiteDriedFlowers ) ),
				new FillableEntry(  1, typeof( GreenDriedFlowers ) ),
				new FillableEntry(  1, typeof( DriedOnions ) ),
				new FillableEntry(  1, typeof( DriedHerbs ) )
			});

        public static FillableContent Inn = new FillableContent(
            1,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Candle ) ),
				new FillableEntry( 1, typeof( Torch ) ),
				new FillableEntry( 1, typeof( Lantern ) )
			});

        public static FillableContent Jeweler = new FillableContent(
            2,
            new Type[]
			{
				typeof( Jeweler )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( GoldRing ) ),
				new FillableEntry( 1, typeof( GoldBracelet ) ),
				new FillableEntry( 1, typeof( GoldEarrings ) ),
				new FillableEntry( 1, typeof( GoldNecklace ) ),
				new FillableEntry( 1, typeof( GoldBeadNecklace ) ),
				new FillableEntry( 1, typeof( Necklace ) ),
				new FillableEntry( 1, typeof( Beads ) ),
				new FillableEntry( 9, Loot.GemTypes )
			});

        public static FillableContent Library = new FillableContent(
            1,
            new Type[]
			{
				typeof( Scribe )
			},
            new FillableEntry[]
			{
				new FillableEntry( 8, Loot.LibraryBookTypes ),
				new FillableEntry( 1, typeof( RedBook ) ),
				new FillableEntry( 1, typeof( BlueBook ) )
			});

        public static FillableContent Mage = new FillableContent(
            2,
            new Type[]
			{
				typeof( Mage ),
				typeof( HolyMage ),
				typeof( MageGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 16, typeof( BlankScroll ) ),
				new FillableEntry( 14, typeof( Spellbook ) ),
				new FillableEntry( 12, Loot.RegularScrollTypes,  0, 8 ),
				new FillableEntry( 11, Loot.RegularScrollTypes,  8, 8 ),
				new FillableEntry( 10, Loot.RegularScrollTypes, 16, 8 ),
				new FillableEntry(  9, Loot.RegularScrollTypes, 24, 8 ),
				new FillableEntry(  8, Loot.RegularScrollTypes, 32, 8 ),
				new FillableEntry(  7, Loot.RegularScrollTypes, 40, 8 ),
				new FillableEntry(  6, Loot.RegularScrollTypes, 48, 8 ),
				new FillableEntry(  5, Loot.RegularScrollTypes, 56, 8 )
			});

        public static FillableContent Merchant = new FillableContent(
            1,
            new Type[]
			{
				typeof( MerchantGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( CheeseWheel ) ),
				new FillableEntry( 1, typeof( CheeseWedge ) ),
				new FillableEntry( 1, typeof( CheeseSlice ) ),
				new FillableEntry( 1, typeof( Eggs ) ),
				new FillableEntry( 4, typeof( Fish ) ),
				new FillableEntry( 2, typeof( RawFishSteak ) ),
				new FillableEntry( 2, typeof( FishSteak ) ),
				new FillableEntry( 1, typeof( Apple ) ),
				new FillableEntry( 2, typeof( Banana ) ),
				new FillableEntry( 2, typeof( Bananas ) ),
				new FillableEntry( 2, typeof( OpenCoconut ) ),
				new FillableEntry( 1, typeof( SplitCoconut ) ),
				new FillableEntry( 1, typeof( Coconut ) ),
				new FillableEntry( 1, typeof( Dates ) ),
				new FillableEntry( 1, typeof( Grapes ) ),
				new FillableEntry( 1, typeof( Lemon ) ),
				new FillableEntry( 1, typeof( Lemons ) ),
				new FillableEntry( 1, typeof( Lime ) ),
				new FillableEntry( 1, typeof( Limes ) ),
				new FillableEntry( 1, typeof( Peach ) ),
				new FillableEntry( 1, typeof( Pear ) ),
				new FillableEntry( 2, typeof( SlabOfBacon ) ),
				new FillableEntry( 2, typeof( Bacon ) ),
				new FillableEntry( 2, typeof( CookedBird ) ),
				new FillableEntry( 2, typeof( RawBird ) ),
				new FillableEntry( 2, typeof( Ham ) ),
				new FillableEntry( 1, typeof( RawLambLeg ) ),
				new FillableEntry( 1, typeof( LambLeg ) ),
				new FillableEntry( 1, typeof( Ribs ) ),
				new FillableEntry( 1, typeof( RawRibs ) ),
				new FillableEntry( 2, typeof( Sausage ) ),
				new FillableEntry( 1, typeof( RawChickenLeg ) ),
				new FillableEntry( 1, typeof( ChickenLeg ) ),
				new FillableEntry( 1, typeof( Watermelon ) ),
				new FillableEntry( 1, typeof( SmallWatermelon ) ),
				new FillableEntry( 3, typeof( Turnip ) ),
				new FillableEntry( 2, typeof( YellowGourd ) ),
				new FillableEntry( 2, typeof( GreenGourd ) ),
				new FillableEntry( 2, typeof( Pumpkin ) ),
				new FillableEntry( 1, typeof( SmallPumpkin ) ),
				new FillableEntry( 2, typeof( Onion ) ),
				new FillableEntry( 2, typeof( Lettuce ) ),
				new FillableEntry( 2, typeof( Squash ) ),
				new FillableEntry( 2, typeof( HoneydewMelon ) ),
				new FillableEntry( 1, typeof( Carrot ) ),
				new FillableEntry( 2, typeof( Cantaloupe ) ),
				new FillableEntry( 2, typeof( Cabbage ) ),
				new FillableEntry( 4, typeof( EarOfCorn ) )
			});

        public static FillableContent Mill = new FillableContent(
            1,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( SackFlour ) )
			});

        public static FillableContent Mine = new FillableContent(
            1,
            new Type[]
			{
				typeof( Miner )
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( Pickaxe ) ),
				new FillableEntry( 2, typeof( Shovel ) ),
				new FillableEntry( 2, typeof( IronIngot ) ),
				new FillableEntry( 1, typeof( ForgedMetal ) )
			});

        public static FillableContent Observatory = new FillableContent(
            1,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( Sextant ) ),
				new FillableEntry( 2, typeof( Clock ) ),
				new FillableEntry( 1, typeof( Spyglass ) )
			});

        public static FillableContent Painter = new FillableContent(
            1,
            new Type[]
			{
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( PaintsAndBrush ) ),
				new FillableEntry( 2, typeof( PenAndInk ) )
			});

        public static FillableContent Provisioner = new FillableContent(
            1,
            new Type[]
			{
				typeof( Provisioner )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( CheeseWheel ) ),
				new FillableEntry( 1, typeof( CheeseWedge ) ),
				new FillableEntry( 1, typeof( CheeseSlice ) ),
				new FillableEntry( 1, typeof( Eggs ) ),
				new FillableEntry( 4, typeof( Fish ) ),
				new FillableEntry( 1, typeof( DirtyFrypan ) ),
				new FillableEntry( 1, typeof( DirtyPan ) ),
				new FillableEntry( 1, typeof( DirtyKettle ) ),
				new FillableEntry( 1, typeof( DirtySmallRoundPot ) ),
				new FillableEntry( 1, typeof( DirtyRoundPot ) ),
				new FillableEntry( 1, typeof( DirtySmallPot ) ),
				new FillableEntry( 1, typeof( DirtyPot ) ),
				new FillableEntry( 1, typeof( Apple ) ),
				new FillableEntry( 2, typeof( Banana ) ),
				new FillableEntry( 2, typeof( Bananas ) ),
				new FillableEntry( 2, typeof( OpenCoconut ) ),
				new FillableEntry( 1, typeof( SplitCoconut ) ),
				new FillableEntry( 1, typeof( Coconut ) ),
				new FillableEntry( 1, typeof( Dates ) ),
				new FillableEntry( 1, typeof( Grapes ) ),
				new FillableEntry( 1, typeof( Lemon ) ),
				new FillableEntry( 1, typeof( Lemons ) ),
				new FillableEntry( 1, typeof( Lime ) ),
				new FillableEntry( 1, typeof( Limes ) ),
				new FillableEntry( 1, typeof( Peach ) ),
				new FillableEntry( 1, typeof( Pear ) ),
				new FillableEntry( 2, typeof( SlabOfBacon ) ),
				new FillableEntry( 2, typeof( Bacon ) ),
				new FillableEntry( 1, typeof( RawFishSteak ) ),
				new FillableEntry( 1, typeof( FishSteak ) ),
				new FillableEntry( 2, typeof( CookedBird ) ),
				new FillableEntry( 2, typeof( RawBird ) ),
				new FillableEntry( 2, typeof( Ham ) ),
				new FillableEntry( 1, typeof( RawLambLeg ) ),
				new FillableEntry( 1, typeof( LambLeg ) ),
				new FillableEntry( 1, typeof( Ribs ) ),
				new FillableEntry( 1, typeof( RawRibs ) ),
				new FillableEntry( 2, typeof( Sausage ) ),
				new FillableEntry( 1, typeof( RawChickenLeg ) ),
				new FillableEntry( 1, typeof( ChickenLeg ) ),
				new FillableEntry( 1, typeof( Watermelon ) ),
				new FillableEntry( 1, typeof( SmallWatermelon ) ),
				new FillableEntry( 3, typeof( Turnip ) ),
				new FillableEntry( 2, typeof( YellowGourd ) ),
				new FillableEntry( 2, typeof( GreenGourd ) ),
				new FillableEntry( 2, typeof( Pumpkin ) ),
				new FillableEntry( 1, typeof( SmallPumpkin ) ),
				new FillableEntry( 2, typeof( Onion ) ),
				new FillableEntry( 2, typeof( Lettuce ) ),
				new FillableEntry( 2, typeof( Squash ) ),
				new FillableEntry( 2, typeof( HoneydewMelon ) ),
				new FillableEntry( 1, typeof( Carrot ) ),
				new FillableEntry( 2, typeof( Cantaloupe ) ),
				new FillableEntry( 2, typeof( Cabbage ) ),
				new FillableEntry( 4, typeof( EarOfCorn ) )
			});

        public static FillableContent Ranger = new FillableContent(
            2,
            new Type[]
			{
				typeof( Ranger ),
				typeof( RangerGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 2, typeof( StuddedChest ) ),
				new FillableEntry( 2, typeof( StuddedLegs ) ),
				new FillableEntry( 2, typeof( StuddedArms ) ),
				new FillableEntry( 2, typeof( StuddedGloves ) ),
				new FillableEntry( 1, typeof( StuddedGorget ) ),

				new FillableEntry( 2, typeof( LeatherChest ) ),
				new FillableEntry( 2, typeof( LeatherLegs ) ),
				new FillableEntry( 2, typeof( LeatherArms ) ),
				new FillableEntry( 2, typeof( LeatherGloves ) ),
				new FillableEntry( 1, typeof( LeatherGorget ) ),

				new FillableEntry( 2, typeof( FeatheredHat ) ),
				new FillableEntry( 1, typeof( CloseHelm ) ),
				new FillableEntry( 1, typeof( TallStrawHat ) ),
				new FillableEntry( 1, typeof( Bandana ) ),
				new FillableEntry( 1, typeof( Cloak ) ),
				new FillableEntry( 2, typeof( Boots ) ),
				new FillableEntry( 2, typeof( ThighBoots ) ),

				new FillableEntry( 2, typeof( GnarledStaff ) ),
				new FillableEntry( 1, typeof( Whip ) ),

				new FillableEntry( 2, typeof( Bow ) ),
				new FillableEntry( 2, typeof( Crossbow ) ),
				new FillableEntry( 2, typeof( HeavyCrossbow ) ),
				new FillableEntry( 4, typeof( Arrow ) )
			});

        public static FillableContent Stables = new FillableContent(
            1,
            new Type[]
			{
				typeof( AnimalTrainer ),
				typeof( GypsyAnimalTrainer )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Carrot ) )
			});

        public static FillableContent Tanner = new FillableContent(
            2,
            new Type[]
			{
				typeof( Tanner ),
				typeof( LeatherWorker ),
				typeof( Furtrader )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( FeatheredHat ) ),
				new FillableEntry( 1, typeof( LeatherArms ) ),
				new FillableEntry( 2, typeof( LeatherLegs ) ),
				new FillableEntry( 2, typeof( LeatherChest ) ),
				new FillableEntry( 2, typeof( LeatherGloves ) ),
				new FillableEntry( 1, typeof( LeatherGorget ) ),
				new FillableEntry( 2, typeof( Leather ) )
			});

        public static FillableContent Tavern = new FillableContent(
            1,
            new Type[]
			{
				typeof( TavernKeeper ),
				typeof( Barkeeper ),
				typeof( Waiter ),
				typeof( Cook )
			},
            new FillableEntry[]
			{
				new FillableBvrge( 1, typeof( BeverageBottle ), BeverageType.Ale ),
				new FillableBvrge( 1, typeof( BeverageBottle ), BeverageType.Wine ),
				new FillableBvrge( 1, typeof( BeverageBottle ), BeverageType.Liquor ),
				new FillableBvrge( 1, typeof( Jug ), BeverageType.Cider )
			});

        public static FillableContent ThiefGuild = new FillableContent(
            1,
            new Type[]
			{
				typeof( Thief ),
				typeof( ThiefGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Lockpick ) ),
				new FillableEntry( 1, typeof( BearMask ) ),
				new FillableEntry( 1, typeof( DeerMask ) ),
				new FillableEntry( 1, typeof( TribalMask ) ),
				new FillableEntry( 1, typeof( HornedTribalMask ) ),
				new FillableEntry( 4, typeof( OrcHelm ) )
			});

        public static FillableContent Tinker = new FillableContent(
            1,
            new Type[]
			{
				typeof( Tinker ),
				typeof( TinkerGuildmaster )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Lockpick ) ),
				new FillableEntry( 2, typeof( Clock ) ),
				new FillableEntry( 2, typeof( ClockParts ) ),
				new FillableEntry( 2, typeof( AxleGears ) ),
				new FillableEntry( 2, typeof( Gears ) ),
				new FillableEntry( 2, typeof( Hinge ) ),
				new FillableEntry( 2, typeof( Sextant ) ),
				new FillableEntry( 2, typeof( SextantParts ) ),
				new FillableEntry( 2, typeof( Axle ) ),
				new FillableEntry( 2, typeof( Springs ) ),
				new FillableEntry( 5, typeof( TinkerTools ) ),
				new FillableEntry( 4, typeof( Key ) ),
				new FillableEntry( 1, typeof( DecoArrowShafts )),
				new FillableEntry( 1, typeof( Lockpicks )),
				new FillableEntry( 1, typeof( ToolKit ))
			});

        public static FillableContent Veterinarian = new FillableContent(
            1,
            new Type[]
			{
				typeof( Veterinarian )
			},
            new FillableEntry[]
			{
				new FillableEntry( 1, typeof( Bandage ) ),
				new FillableEntry( 1, typeof( MortarPestle ) ),
				new FillableEntry( 1, typeof( LesserHealPotion ) ),
				new FillableEntry( 1, typeof( Carrot ) )
			});

        public static FillableContent Weaponsmith = new FillableContent(
            2,
            new Type[]
			{
				typeof( Weaponsmith )
			},
            new FillableEntry[]
			{
				new FillableEntry( 8, Loot.WeaponTypes ),
				new FillableEntry( 1, typeof( Arrow ) )
			});

        public static FillableContent Lookup(FillableContentType type)
        {
            int v = (int)type;

            if (v >= 0 && v < m_ContentTypes.Length)
                return m_ContentTypes[v];

            return null;
        }

        public static FillableContentType Lookup(FillableContent content)
        {
            if (content == null)
                return FillableContentType.None;

            return (FillableContentType)Array.IndexOf(m_ContentTypes, content);
        }

        private static Hashtable m_AcquireTable;

        private static FillableContent[] m_ContentTypes = new FillableContent[]
			{
				Weaponsmith,	Provisioner,	Mage,
				Alchemist,		Armorer,		ArtisanGuild,
				Baker,			Bard,			Blacksmith,
				Bowyer,			Butcher,		Carpenter,
				Clothier,		Cobbler,		Docks,
				Farm,			FighterGuild,	Guard,
				Healer,			Herbalist,		Inn,
				Jeweler,		Library,		Merchant,
				Mill,			Mine,			Observatory,
				Painter,		Ranger,			Stables,
				Tanner,			Tavern,			ThiefGuild,
				Tinker,			Veterinarian
			};

        public static FillableContent Acquire(Point3D loc, Map map)
        {
            if (map == null || map == Map.Internal)
                return null;

            if (m_AcquireTable == null)
            {
                m_AcquireTable = new Hashtable();

                for (int i = 0; i < m_ContentTypes.Length; ++i)
                {
                    FillableContent fill = m_ContentTypes[i];

                    for (int j = 0; j < fill.m_Vendors.Length; ++j)
                        m_AcquireTable[fill.m_Vendors[j]] = fill;
                }
            }

            Mobile nearest = null;
            FillableContent content = null;

            foreach (Mobile mob in map.GetMobilesInRange(loc, 20))
            {
                if (nearest != null && mob.GetDistanceToSqrt(loc) > nearest.GetDistanceToSqrt(loc) && !(nearest is Cobbler && mob is Provisioner))
                    continue;

                FillableContent check = m_AcquireTable[mob.GetType()] as FillableContent;

                if (check != null)
                {
                    nearest = mob;
                    content = check;
                }
            }

            return content;
        }
    }

    #region Fillable Container Type List

    #region LibraryBookcase

    [Flipable(0xA97, 0xA99, 0xA98, 0xA9A, 0xA9B, 0xA9C)]
    public class LibraryBookcase : FillableContainer
    {
        public override bool IsLockable { get { return false; } }
        public override int SpawnThreshold { get { return 5; } }

        protected override int GetSpawnCount()
        {
            return (5 - GetItemsCount());
        }

        public override void AcquireContent()
        {
            if (m_Content != null)
                return;

            m_Content = FillableContent.Library;

            if (m_Content != null)
                Respawn();
        }

        [Constructable]
        public LibraryBookcase()
            : base(0xA97)
        {
            Weight = 1.0;
        }

        public LibraryBookcase(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();

            if (version == 0 && m_Content == null)
                Timer.DelayCall(TimeSpan.Zero, new TimerCallback(AcquireContent));
        }
    }

    #endregion Edited By: A.A.R

    #region FillableLargeCrate

    [Flipable(0xE3D, 0xE3C)]
    public class FillableLargeCrate : FillableContainer
    {
        [Constructable]
        public FillableLargeCrate()
            : base(0xE3D)
        {
            Weight = 1.0;
        }

        public FillableLargeCrate(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();
        }
    }

    #endregion Edited By: A.A.R

    #region FillableSmallCrate

    [Flipable(0x9A9, 0xE7E)]
    public class FillableSmallCrate : FillableContainer
    {
        [Constructable]
        public FillableSmallCrate()
            : base(0x9A9)
        {
            Weight = 1.0;
        }

        public FillableSmallCrate(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();
        }
    }

    #endregion Edited By: A.A.R

    #region FillableWoodenBox

    [Flipable(0x9AA, 0xE7D)]
    public class FillableWoodenBox : FillableContainer
    {
        [Constructable]
        public FillableWoodenBox()
            : base(0x9AA)
        {
            Weight = 4.0;
        }

        public FillableWoodenBox(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region FillableMetalBox

    [Flipable(0x9A8, 0xE80)]
    public class FillableMetalBox : FillableContainer
    {
        [Constructable]
        public FillableMetalBox()
            : base(0x9A8)
        {
        }

        public FillableMetalBox(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();

            if (version == 0 && Weight == 3)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region FillableBarrel

    public class FillableBarrel : FillableContainer
    {
        public override bool IsLockable { get { return false; } }

        [Constructable]
        public FillableBarrel()
            : base(0xE77)
        {
        }

        public FillableBarrel(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadEncodedInt();

            if (version == 0 && Weight == 25)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region FillableMetalChest

    [Flipable(0x9AB, 0xE7C)]
    public class FillableMetalChest : FillableContainer
    {
        [Constructable]
        public FillableMetalChest()
            : base(0x9AB)
        {
        }

        public FillableMetalChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 25)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region FillableMetalGoldenChest

    [Flipable(0xE41, 0xE40)]
    public class FillableMetalGoldenChest : FillableContainer
    {
        [Constructable]
        public FillableMetalGoldenChest()
            : base(0xE41)
        {
        }

        public FillableMetalGoldenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 25)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region FillableWoodenChest

    [Flipable(0xE43, 0xE42)]
    public class FillableWoodenChest : FillableContainer
    {
        [Constructable]
        public FillableWoodenChest()
            : base(0xE43)
        {
        }

        public FillableWoodenChest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            if (version == 0 && Weight == 2)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #endregion Edited By: A.A.R


    //------------------------------------------------------------------------------------//


    /// <summary>
    /// FurnitureContainerConfiguration
    /// </summary>

    public class DynamicFurniture
    {
        private static Dictionary<Container, Timer> m_Table = new Dictionary<Container, Timer>();

        public static bool Open(Container c, Mobile m)
        {
            if (m_Table.ContainsKey(c))
            {
                c.SendRemovePacket();
                Close(c);
                c.Delta(ItemDelta.Update);
                c.ProcessDelta();
                return false;
            }

            if (c is Armoire || c is FancyArmoire)
            {
                Timer t = new FurnitureTimer(c, m);
                t.Start();
                m_Table[c] = t;

                switch (c.ItemID)
                {
                    case 0xA4D: c.ItemID = 0xA4C; break;
                    case 0xA4F: c.ItemID = 0xA4E; break;
                    case 0xA51: c.ItemID = 0xA50; break;
                    case 0xA53: c.ItemID = 0xA52; break;
                }
            }

            return true;
        }

        public static void Close(Container c)
        {
            Timer t = null;

            m_Table.TryGetValue(c, out t);

            if (t != null)
            {
                t.Stop();
                m_Table.Remove(c);
            }

            if (c is Armoire || c is FancyArmoire)
            {
                switch (c.ItemID)
                {
                    case 0xA4C: c.ItemID = 0xA4D; break;
                    case 0xA4E: c.ItemID = 0xA4F; break;
                    case 0xA50: c.ItemID = 0xA51; break;
                    case 0xA52: c.ItemID = 0xA53; break;
                }
            }
        }
    }

    public class FurnitureTimer : Timer
    {
        private Container m_Container;
        private Mobile m_Mobile;

        public FurnitureTimer(Container c, Mobile m): base(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5))
        {
            Priority = TimerPriority.TwoFiftyMS;

            m_Container = c;
            m_Mobile = m;
        }

        protected override void OnTick()
        {
            if (m_Mobile.Map != m_Container.Map || !m_Mobile.InRange(m_Container.GetWorldLocation(), 3))
                DynamicFurniture.Close(m_Container);
        }
    }

    #region  Furniture Container Type List

    #region TallCabinet

    [Furniture]
    [Flipable(0x2815, 0x2816)]
    public class TallCabinet : BaseContainer
    {
        [Constructable]
        public TallCabinet()
            : base(0x2815)
        {
            Weight = 1.0;
        }

        public TallCabinet(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region ShortCabinet

    [Furniture]
    [Flipable(0x2817, 0x2818)]
    public class ShortCabinet : BaseContainer
    {
        [Constructable]
        public ShortCabinet()
            : base(0x2817)
        {
            Weight = 1.0;
        }

        public ShortCabinet(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region RedArmoire

    [Furniture]
    [Flipable(0x2857, 0x2858)]
    public class RedArmoire : BaseContainer
    {
        [Constructable]
        public RedArmoire()
            : base(0x2857)
        {
            Weight = 1.0;
        }

        public RedArmoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region CherryArmoire

    [Furniture]
    [Flipable(0x285D, 0x285E)]
    public class CherryArmoire : BaseContainer
    {
        [Constructable]
        public CherryArmoire()
            : base(0x285D)
        {
            Weight = 1.0;
        }

        public CherryArmoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region MapleArmoire

    [Furniture]
    [Flipable(0x285B, 0x285C)]
    public class MapleArmoire : BaseContainer
    {
        [Constructable]
        public MapleArmoire()
            : base(0x285B)
        {
            Weight = 1.0;
        }

        public MapleArmoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region ElegantArmoire

    [Furniture]
    [Flipable(0x2859, 0x285A)]
    public class ElegantArmoire : BaseContainer
    {
        [Constructable]
        public ElegantArmoire()
            : base(0x2859)
        {
            Weight = 1.0;
        }

        public ElegantArmoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region FullBookcase

    [Furniture]
    [Flipable(0xa97, 0xa99, 0xa98, 0xa9a, 0xa9b, 0xa9c)]
    public class FullBookcase : BaseContainer
    {
        [Constructable]
        public FullBookcase()
            : base(0xA97)
        {
            Weight = 1.0;
        }

        public FullBookcase(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region EmptyBookcase

    [Furniture]
    [Flipable(0xa9d, 0xa9e)]
    public class EmptyBookcase : BaseContainer
    {
        [Constructable]
        public EmptyBookcase()
            : base(0xA9D)
        {
        }

        public EmptyBookcase(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version == 0 && Weight == 1.0)
                Weight = -1;
        }
    }

    #endregion Edited By: A.A.R

    #region Drawer

    [Furniture]
    [Flipable(0xa2c, 0xa34)]
    public class Drawer : BaseContainer
    {
        [Constructable]
        public Drawer()
            : base(0xA2C)
        {
            Weight = 1.0;
        }

        public Drawer(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region FancyDrawer

    [Furniture]
    [Flipable(0xa30, 0xa38)]
    public class FancyDrawer : BaseContainer
    {
        [Constructable]
        public FancyDrawer()
            : base(0xA30)
        {
            Weight = 1.0;
        }

        public FancyDrawer(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }

    #endregion Edited By: A.A.R

    #region Armoire

    [Furniture]
    [Flipable(0xa4f, 0xa53)]
    public class Armoire : BaseContainer
    {
        [Constructable]
        public Armoire()
            : base(0xA4F)
        {
            Weight = 1.0;
        }

        public override void DisplayTo(Mobile m)
        {
            if (DynamicFurniture.Open(this, m))
                base.DisplayTo(m);
        }

        public Armoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            DynamicFurniture.Close(this);
        }
    }

    #endregion Edited By: A.A.R

    #region FancyArmoire

    [Furniture]
    [Flipable(0xa4d, 0xa51)]
    public class FancyArmoire : BaseContainer
    {
        [Constructable]
        public FancyArmoire()
            : base(0xA4D)
        {
            Weight = 1.0;
        }

        public override void DisplayTo(Mobile m)
        {
            if (DynamicFurniture.Open(this, m))
                base.DisplayTo(m);
        }

        public FancyArmoire(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            DynamicFurniture.Close(this);
        }
    }

    #endregion Edited By: A.A.R

    #endregion Edited By: A.A.R
}